package cn.linkedcare.lib.cloud.call;

import com.google.gson.Gson;

import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.CallbackContext;

import org.apache.cordova.PluginResult;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import cn.linkedcare.lib.call.CallConfig;
import cn.linkedcare.lib.call.CallManager;
import cn.linkedcare.lib.call.Customer;

/**
 * This class echoes a string called from JavaScript.
 */
public class CloudCall extends CordovaPlugin implements CallManager.CallActionClickListener {

    private Gson mGson = new Gson();

    private CallManager mCallManager;

    private CallbackContext mCallActionCallbackContext = null;

    @Override
    protected void pluginInitialize() {
        super.pluginInitialize();
        CallManager.init(cordova.getActivity().getApplication());
        mCallManager = CallManager.get();
        mCallManager.addCallActionClickListener(this);
    }

    @Override
    public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
        if ("cloudCallNativeServer".equals(action)) {
            return cloudCallNativeServer(args, callbackContext);
        } else if ("nativeCallBackAction".equals(action)) {
            mCallActionCallbackContext = callbackContext;
            return true;
        }

        return false;
    }

    private boolean cloudCallNativeServer(JSONArray args, CallbackContext callbackContext) throws JSONException {
        if (args == null || args.length() < 1) {
            callbackContext.error("Param invalid.");
            return false;
        }

        final String action = args.getString(0);

        if ("logoutServer".equals(action)) {
            return logout();
        } else {
            JSONObject param;

            if (args.length() < 2 || (param = args.getJSONObject(1)) == null) {
                callbackContext.error("Param invalid.");
                return false;
            }

            if ("setCloudConfig".equals(action)) {
                return setConfig(param, callbackContext);
            } else if ("loginServer".equals(action)) {
                return login(callbackContext, param);
            } else if ("callPatients".equals(action)) {
                return callOut(param, callbackContext);
            } else if ("cloudCallListInfo".equals(action)) {
                return startCallRecords(param, callbackContext);
            }
        }

        return false;
    }

    private boolean setConfig(JSONObject param, CallbackContext callbackContext) {
        cordova.getActivity().runOnUiThread(() -> {
            CallConfig callConfig;

            try {
                callConfig = mGson.fromJson(param.toString(), CallConfig.class);
            } catch (RuntimeException e) {
                return;
            }

            if (callConfig == null) return;

            mCallManager.setConfig(callConfig);
        });

        return true;
    }

    private boolean login(CallbackContext callbackContext, JSONObject param) {
        cordova.getActivity().runOnUiThread(() -> {
            CallConfig callConfig;

            try {
                callConfig = mGson.fromJson(param.toString(), CallConfig.class);
            } catch (RuntimeException e) {
                return;
            }

            if (callConfig == null) return;

            mCallManager.login(cordova.getActivity(), callConfig);
        });

        return true;
    }

    private boolean logout() {
        cordova.getActivity().runOnUiThread(() -> {
            mCallManager.logout();
        });

        return true;
    }

    private boolean callOut(JSONObject param, CallbackContext callbackContext) {
        cordova.getActivity().runOnUiThread(() -> {
            Customer customer;

            try {
                customer = mGson.fromJson(param.toString(), Customer.class);
            } catch (RuntimeException e) {
                return;
            }

            if (customer == null) return;

            mCallManager.callOut(cordova.getActivity(), customer);
        });

        return true;
    }

    private boolean startCallRecords(JSONObject param, CallbackContext callbackContext) {
        cordova.getActivity().runOnUiThread(() -> {
            String customerId = "";

            try {
                customerId = param.getString("id");
            } catch (JSONException e) {
                e.printStackTrace();
            }

            mCallManager.startCallRecords(cordova.getActivity(), customerId);
        });

        return true;
    }

    @Override
    public void onClick(CallConfig.CallActionEvent callActionEvent) {
        if (mCallActionCallbackContext == null) return;

        cordova.getActivity().runOnUiThread(() -> {
            String param;
            try {
                param = mGson.toJson(callActionEvent);
            } catch (RuntimeException e) {
                return;
            }
            PluginResult result = new PluginResult(PluginResult.Status.OK, param);
            result.setKeepCallback(true);
            mCallActionCallbackContext.sendPluginResult(result);
        });
    }

}
